home *** CD-ROM | disk | FTP | other *** search
- #include "solid.h"
-
- void define_solid(int this_obj_type)
- /* Constructs solid descriptor */
- {
- struct obj_defn *this_defn_ptr;
- struct facet *facet_ptr;
- struct vertex *vertex_ptr;
- int sweep_index; /* varies from 0 to "sweeps" - 1;
- 0 and "sweeps" - 1 are polar sweeps */
- int facet_index; /* index of facets for each sweep;
- varies from 0 to facet_max */
- int sweep_count; /* number of sweeps to make */
- int facet_max; /* number of facets per sweep */
- int vertex_ref_index; /* index of current vertex */
- int vertex_s; /* index of 1st vertex for sweep */
- float vert_angle; /* angle first side of facet
- forms with positive x axis in x-y plane */
- float vert_angle_init; /* initial vert_angle */
- float vert_delta; /* angle formed by sides of
- current facet in x-y plane */
- float horiz_angle; /* angle 1st side of facet forms
- with positive x axis in x-z plane */
- float vert_scale; /* scaling factor in xy plane */
- float horiz_scale; /* scaling factor in xz plane */
- int num_vertices, num_facets, num_vertex_refs;
- int region; /* -1 = north polar, 1 = south polar,
- 0 elsewhere */
- float sqrt2;
-
- sqrt2 = sqrt(2.0);
- switch(this_obj_type) {
- case CUBE_OBJ: {
- sweep_count = 3;
- facet_max = 4;
- vert_angle_init = PI / 4.0;
- vert_delta = PI / 2.0;
- vert_scale = 1.0 / sqrt2;
- horiz_scale = 2.0 / sqrt2;
- num_vertices = 8;
- num_facets = 6;
- num_vertex_refs = 24;
- break;
- }
- case SPHERE_OBJ: {
- sweep_count = sweeps;
- facet_max = facets;
- vert_angle_init = PI / (float)sweeps;
- vert_delta = PI / (float)sweeps;
- vert_scale = 0.5;
- horiz_scale = 1.0;
- num_vertices = (sweep_count - 1) *
- facet_max + 2;
- num_facets = sweep_count * facet_max;
- num_vertex_refs = (4 * sweep_count - 2) *
- facet_max;
- break;
- }
- case CYLIND_OBJ: {
- sweep_count = 3;
- facet_max = facets;
- vert_angle_init = PI / 4.0;
- vert_delta = PI / 2.0;
- vert_scale = 1.0 / sqrt2;
- horiz_scale = 2.0 / sqrt2;
- num_vertices = 2 * facet_max;
- num_facets = 2 + facet_max;
- num_vertex_refs = 6 * facet_max;
- break;
- }
- case CONE_OBJ: {
- sweep_count = 2;
- facet_max = facets;
- vert_angle_init = 3.0 * PI / 4.0;
- vert_scale = 1.0 / sqrt2;
- horiz_scale = 2.0 / sqrt2;
- num_vertices = facet_max + 1;
- num_facets = facet_max + 1;
- num_vertex_refs = 4 * facet_max;
- break;
- }
- default:
- quit(ERR_OBJTYPE, __FILE__, __LINE__);
- }
- if ((vertex_ptr = (struct vertex *)malloc(
- num_vertices * sizeof(struct vertex))) == NULL)
- /* allocate storage for vertices */
- quit(ERR_MEMORY, __FILE__, __LINE__);
-
- if ((facet_ptr = (struct facet *)malloc(num_facets
- * sizeof(struct facet) + num_vertex_refs *
- sizeof(INDEX))) == NULL) /* allocate storage
- for facet descriptors */
- quit(ERR_MEMORY, __FILE__, __LINE__);
-
- /* construct definition descriptor */
- if ((this_defn_ptr = (struct obj_defn *)malloc(
- sizeof(struct obj_defn))) == NULL)
- quit(ERR_MEMORY, __FILE__, __LINE__);
- this_defn_ptr->vertex_count = num_vertices;
- this_defn_ptr->vertex_first = vertex_ptr;
- this_defn_ptr->facet_count = num_facets;
- this_defn_ptr->facet_first = facet_ptr;
-
- /* fill in vertex coords and facet descriptors */
- vertex_s = 0;
- vert_angle = vert_angle_init;
- /* main loop; each execution performs one sweep */
- for (sweep_index = 0; sweep_index < sweep_count;
- ++sweep_index) {
- region = (sweep_index == 0) ? -1 :
- ((sweep_index == sweep_count - 1) ? 1 : 0);
- /* construct vertices */
- if ((region != 0 && this_obj_type ==
- SPHERE_OBJ) || (region == -1 &&
- this_obj_type == CONE_OBJ)) { /* construct
- polar vertex */
- vertex_ptr->coord[0] = vertex_ptr->coord[2]
- = 0.0;
- vertex_ptr->coord[1] = 0.5 * ((sweep_index
- == 0) ? 1 : -1);
- ++vertex_ptr; /* point to next vertex */
- ++vertex_s;
- }
- if (region != 1) { /* construct normal vertices
- counterclockwise along bottom edge of sweep
- as viewed from top of object */
- horiz_angle = 2.0 * PI - PI /
- (float)facet_max;
- for (facet_index = 0; facet_index <
- facet_max; ++facet_index) {
- vertex_ptr->coord[0] = vert_scale *
- sin(vert_angle) * horiz_scale *
- cos(horiz_angle); /* x-coord */
- vertex_ptr->coord[1] = vert_scale *
- cos(vert_angle); /* y-coord */
- vertex_ptr->coord[2] = vert_scale *
- sin(vert_angle) * horiz_scale *
- sin(horiz_angle); /* z-coord */
- ++vertex_ptr; /* point to next */
- horiz_angle -= 2.0 * PI / (float)
- facet_max;
- }
- }
- /* construct facet descriptors for sweep */
- switch (region) {
- case -1:
- case 1: { /* polar region: construct
- triangular facets of sphere or cone or
- top facet of cube or cylinder */
- if (this_obj_type == SPHERE_OBJ ||
- (this_obj_type == CONE_OBJ &&
- region == -1)) { /* polar
- triangular facets of sphere or
- cone */
- for (facet_index = 0; facet_index <
- facet_max; ++facet_index,
- facet_ptr = ADV_FACET_PTR(3)) {
- facet_ptr->vertex_count = 3;
- facet_ptr->vertex_index[0] =
- (region == -1) ? 0 :
- (num_vertices - 1);
- /* polar vertex */
- facet_ptr->vertex_index[1] =
- (region == -1) ?
- ((facet_index == 0) ?
- facet_max : facet_index) :
- (num_vertices - facet_max -
- 1 + facet_index);
- facet_ptr->vertex_index[2] =
- (region == -1) ? (1 +
- facet_index) :
- ((num_vertices - facet_max
- - 2) + ((facet_index == 0)
- ? facet_max :
- facet_index));
- }
- }
- if (this_obj_type == CUBE_OBJ ||
- this_obj_type == CYLIND_OBJ ||
- (region == 1 && this_obj_type ==
- CONE_OBJ)) { /* top or bottom facet
- of cube or cylinder or bottom facet
- of cone */
- facet_ptr->vertex_count =
- facet_max;
- for (facet_index = 0; facet_index
- < facet_max; ++facet_index)
- facet_ptr->vertex_index
- [facet_index] = (region == -1)
- ? facet_index : (num_vertices -
- facet_index - 1);
- facet_ptr = ADV_FACET_PTR
- (facet_max);
- }
- break;
- }
- case 0: { /* construct rectangular facets
- between lines of latitude */
- for (facet_index = 0; facet_index <
- facet_max; ++facet_index, facet_ptr
- = ADV_FACET_PTR(4)) {
- facet_ptr->vertex_count = 4;
- facet_ptr->vertex_index[0] =
- vertex_s - facet_max +
- facet_index; facet_ptr->
- vertex_index[1] = vertex_s -
- facet_max - 1 + ((facet_index
- == 0) ? facet_max :
- facet_index);
- facet_ptr->vertex_index[2] =
- (facet_index == 0) ? (vertex_s
- + facet_max - 1) : (vertex_s -
- 1 + facet_index);
- facet_ptr->vertex_index[3] =
- vertex_s + facet_index;
- }
- }
- }
- vert_angle += vert_delta;
- vertex_s += facet_max;
- }
- defn_ptr[this_obj_type] = this_defn_ptr; /* save
- pointer to definition */
- return;
- }
-